package com.bluestone.context;

import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.bluestone.assertor.AssertorFilter;
import com.bluestone.assertor.IAssertor;
import com.bluestone.config.ActionConfig;
import com.bluestone.config.AssertorConfig;
import com.bluestone.config.BluestoneConfig;
import com.bluestone.config.ConfigUtil;
import com.bluestone.config.FilterConfig;
import com.bluestone.config.ListenerConfig;
import com.bluestone.listener.IListener;
import com.bluestone.util.Util;

public class ConfigContext extends ContextBase {

	private static ConfigContext context = null;
	private BluestoneConfig config = null;
	private String configFile = "./bluestone_cfg.xml";	
	private HashMap listeners = new HashMap();
	HashMap<String, IAssertor> assertors = new HashMap<String, IAssertor>();

	public BluestoneConfig getConfig() {
		return config;
	}

	public HashMap<String, IAssertor> getAssertors() {
		return assertors;
	}
	public HashMap getContextListeners() {
		return (HashMap) listeners.get("context");
	}

	public void setAssertors(HashMap<String, IAssertor> assertors) {
		this.assertors = assertors;
	}

	public void setConfig(BluestoneConfig config) {
		this.config = config;
	}
	
	public static ConfigContext getInstance(){
		if(context==null){
			context = new ConfigContext();
			context.loadConfigFile();
		}
		return context;
	}
	
	private void loadConfigFile(){
		addExecuteLog("load luster config file  ->"+configFile);
		boolean flag = true;
		Object obj = Util.loadObjectFromFile(configFile,BluestoneConfig.class);
		if(obj!=null){
			config =  (BluestoneConfig)obj;
			ConfigUtil.getInstance();
			flag =  loadListeners();
			flag = loadAssertors();
		}else{
			flag =  false;
		}
		if(flag){
			addExecuteLog("load luster config file successful!");
		}else{
			addExecuteLog("load luster config file failure!");
		}
		
	}	
	private boolean loadListeners(){
		HashMap<String, IListener> projectListeners = new HashMap<String, IListener>();
		HashMap<String, PropertyChangeListener> contextListeners = new HashMap<String, PropertyChangeListener>();
		
		try{
			List<ListenerConfig> listenerConfigs = getConfig().getListeners();
			for(ListenerConfig listenerConfig:listenerConfigs){
				String className = listenerConfig.getClassName();
				String name= listenerConfig.getName();
				String type = listenerConfig.getType();
				if("project".equalsIgnoreCase(type)){
					if(className!=null && className.length()>0){
						Object obj = Class.forName(className).newInstance();
						if(IListener.class.isInstance(obj)){
							addExecuteLog("load listener "+name + "-->"+className);
							((IListener)obj).execute(this);
							projectListeners.put(name, (IListener)obj);
						}
					}
				}else if("context".equalsIgnoreCase(type)){
					if(className!=null && className.length()>0){
						Object obj = Class.forName(className).newInstance();
						if(PropertyChangeListener.class.isInstance(obj)){
							addExecuteLog("load listener "+name + "-->"+className);
							contextListeners.put(name, (PropertyChangeListener)obj);
						}
					}					
				}
			}
			listeners.put("project", projectListeners);
			listeners.put("context", contextListeners);
			return true;
		}catch(Exception me){
			addExecuteLog("can't load listeners");
			return false;
		}
	}
	private boolean loadAssertors(){

		try {
			List<AssertorConfig> assertorConfigs = getConfig().getAssertors();
			for (AssertorConfig assertorConfig : assertorConfigs) {
				String className = assertorConfig.getClassName();
				String name = assertorConfig.getName();
				String isdefault = assertorConfig.getIsDefault();
				if (className != null && className.length() > 0) {
					Object obj = Class.forName(className).newInstance();
					if (IAssertor.class.isInstance(obj)) {
						addExecuteLog("load assertor " + name + "-->"
								+ className);
						List<FilterConfig> filters = assertorConfig
								.getFilters();
						for (FilterConfig filter : filters) {
							String filterClass = filter.getClassName();
							String filterName = filter.getName();
							Object filterObj = Class.forName(filterClass)
									.newInstance();
							((IAssertor) obj)
									.addFilter((AssertorFilter) filterObj);
							addExecuteLog("load assertor filter "
									+ filterName + "-->" + filterClass);
						}
						if ("y".equalsIgnoreCase(isdefault)) {
							((IAssertor) obj).setDefault(true);
						} else {
							((IAssertor) obj).setDefault(false);
						}
						((IAssertor)obj).start();
						assertors.put(name,(IAssertor)obj);
					}
				}

			}
			return true;
		} catch (Exception me) {
			addExecuteLog("can't load assertor");
			return false;
		} 
	}
	
}
